/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ui;

import domain.Task;
import service.TaskManager;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author Дмитрий
 */
public class GUI extends javax.swing.JFrame {

    private TaskManager manager;
    private List<Task> tasks;
    private List<Task> expiredTasks;

    private TaskTableModel allModel;
    private TaskTableModel activeModel;
    private ChangeFrame dialog;
    private TrayIcon icon;

    /**
     * Creates new form GUI
     */
    public GUI(TaskManager manager) {
        this.tasks = manager.getTasks();
        this.manager = manager;
        this.expiredTasks = manager.getExpiredTasks();
        Image image = Toolkit.getDefaultToolkit().getImage("task.jpg");
        setIconImage(image);
        if (SystemTray.isSupported()) {
            icon = new TrayIcon(image);
            icon.setToolTip("Task Manager");
            icon.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    showFrame();
                }

            });
            addWindowListener(new WindowAdapter() {

                @Override
                public void windowIconified(WindowEvent e) {
                    GUI.this.setVisible(false);
                    try {
                        SystemTray.getSystemTray().add(icon);
                    } catch (AWTException e1) {
                        e1.printStackTrace();
                    }
                }

            });
        }
        initComponents();
    }

    private void showFrame() {
        GUI.this.setVisible(true);
        GUI.this.setExtendedState(GUI.NORMAL);
        TabbedPane.setSelectedIndex(0);
        SystemTray.getSystemTray().remove(icon);
    }

    public void makeTaskForExecute(Task task) {
        activeModel.getTasks().add(task);
        activeModel.repaint();
        allModel.repaint();
        showFrame();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        TabbedPane = new javax.swing.JTabbedPane();
        ActiveTab = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        ActiveTable = new javax.swing.JTable();
        EndButton = new javax.swing.JButton();
        DelayButton = new javax.swing.JButton();
        DelayComboBox = new javax.swing.JComboBox();
        ActiveLabel = new javax.swing.JLabel();
        AllTab = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        AllTable = new javax.swing.JTable();
        CreateButton = new javax.swing.JButton();
        ChangeButton = new javax.swing.JButton();
        DeleteButton = new javax.swing.JButton();
        AllLabel = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Task Manager v1.0");

        activeModel = new TaskTableModel(expiredTasks);
        allModel = new TaskTableModel(tasks);
        ActiveTable.setModel(activeModel);
        ActiveTable.setRowHeight(30);
        jScrollPane2.setViewportView(ActiveTable);

        EndButton.setText("End Task");
        EndButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EndButtonActionPerformed(evt);
            }
        });

        DelayButton.setText("Delay Task");
        DelayButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DelayButtonActionPerformed(evt);
            }
        });

        DelayComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "15 minutes", "1 hour", "1 day" }));
        DelayComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DelayComboBoxActionPerformed(evt);
            }
        });

        ActiveLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        ActiveLabel.setText("Active Tasks");

        javax.swing.GroupLayout ActiveTabLayout = new javax.swing.GroupLayout(ActiveTab);
        ActiveTab.setLayout(ActiveTabLayout);
        ActiveTabLayout.setHorizontalGroup(
            ActiveTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ActiveTabLayout.createSequentialGroup()
                .addGroup(ActiveTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ActiveTabLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                    .addGroup(ActiveTabLayout.createSequentialGroup()
                        .addGap(117, 117, 117)
                        .addComponent(ActiveLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 122, Short.MAX_VALUE)))
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ActiveTabLayout.createSequentialGroup()
                .addGap(0, 0, Short.MAX_VALUE)
                .addComponent(DelayComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(DelayButton, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(EndButton, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(38, 38, 38))
        );
        ActiveTabLayout.setVerticalGroup(
            ActiveTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ActiveTabLayout.createSequentialGroup()
                .addGap(5, 5, 5)
                .addComponent(ActiveLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(ActiveTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(DelayComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(DelayButton)
                    .addComponent(EndButton))
                .addContainerGap())
        );

        TabbedPane.addTab("Active", ActiveTab);

        AllTable.setModel(allModel);
        AllTable.setRowHeight(30);
        jScrollPane3.setViewportView(AllTable);

        CreateButton.setText("Create Task");
        CreateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CreateButtonActionPerformed(evt);
            }
        });

        ChangeButton.setText("Change Task");
        ChangeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ChangeButtonActionPerformed(evt);
            }
        });

        DeleteButton.setText("Delete Task");
        DeleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DeleteButtonActionPerformed(evt);
            }
        });

        AllLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        AllLabel.setText("All Tasks");

        jButton1.setText("Refresh");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout AllTabLayout = new javax.swing.GroupLayout(AllTab);
        AllTab.setLayout(AllTabLayout);
        AllTabLayout.setHorizontalGroup(
            AllTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(AllTabLayout.createSequentialGroup()
                .addGroup(AllTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(AllTabLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                    .addGroup(AllTabLayout.createSequentialGroup()
                        .addGroup(AllTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(AllTabLayout.createSequentialGroup()
                                .addGap(115, 115, 115)
                                .addComponent(AllLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 185, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(AllTabLayout.createSequentialGroup()
                                .addGap(19, 19, 19)
                                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(CreateButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(ChangeButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(DeleteButton)))
                        .addGap(0, 18, Short.MAX_VALUE)))
                .addContainerGap())
        );
        AllTabLayout.setVerticalGroup(
            AllTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(AllTabLayout.createSequentialGroup()
                .addGap(5, 5, 5)
                .addComponent(AllLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(AllTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(CreateButton)
                    .addComponent(jButton1)
                    .addComponent(ChangeButton)
                    .addComponent(DeleteButton))
                .addContainerGap())
        );

        TabbedPane.addTab("All", AllTab);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TabbedPane)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TabbedPane)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void DeleteButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_DeleteButtonActionPerformed
        try {
            int i = AllTable.getSelectedRow();
            Task task = allModel.getTasks().get(i);
            if (manager.checkVersion(task.getId(), task.getVersion())) {
                manager.delete(task.getId());
                activeModel.getTasks().remove(task);
                activeModel.repaint();
                allModel.repaint();
            } else
                showWarningMessage("Task has been change", "Please, click refresh button to update list of tasks");
        } catch (Exception e) {
            e.printStackTrace();
            showWarningMessage("Something goes wrong...", "Maybe you need select a row?");
        }
    }//GEN-LAST:event_DeleteButtonActionPerformed

    private void CreateButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_CreateButtonActionPerformed
        try {
            dialog = new ChangeFrame(manager, new Task(), allModel, activeModel);
            dialog.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
            showWarningMessage("Something goes wrong...", "Shit happened...");
        }
    }//GEN-LAST:event_CreateButtonActionPerformed

    private void EndButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EndButtonActionPerformed
        try {

            int i = ActiveTable.getSelectedRow();
            Task task = activeModel.getTasks().get(i);
            if (manager.checkVersion(task.getId(), task.getVersion())) {
                manager.delete(task.getId());
                activeModel.getTasks().remove(i);
                activeModel.repaint();
                allModel.repaint();
            } else
                showWarningMessage("Task has been change", "Please, click refresh button to update list of tasks");
        } catch (Exception e) {
            showWarningMessage("Something goes wrong...", "Maybe you need select a row?");
        }
    }//GEN-LAST:event_EndButtonActionPerformed

    private void DelayButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DelayButtonActionPerformed
        try {
            int i = ActiveTable.getSelectedRow();
            Task task = activeModel.getTasks().get(i);
            if (manager.checkVersion(task.getId(), task.getVersion())) {
                String value = DelayComboBox.getItemAt(DelayComboBox.getSelectedIndex()).toString();
                Date date = new Date();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                if (value.equals("15 minutes")) {
                    calendar.add(Calendar.MINUTE, 1);
                } else if (value.equals("1 hour")) {
                    calendar.add(Calendar.HOUR_OF_DAY, 1);
                } else if (value.equals("1 day")) {
                    calendar.add(Calendar.DAY_OF_YEAR, 1);
                }
                date = calendar.getTime();
                task.setDate(date);
                manager.update(task.getId(), task.getName(), task.getDescription(), date, task.getVersion());
                activeModel.getTasks().remove(i);
                activeModel.repaint();
                allModel.repaint();
            } else
                showWarningMessage("Task has been change", "Please, click refresh button to update list of tasks");
        } catch (Exception e) {
            showWarningMessage("Something goes wrong...", "Maybe you need select a row?");
        }
    }//GEN-LAST:event_DelayButtonActionPerformed

    private void DelayComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DelayComboBoxActionPerformed

    }//GEN-LAST:event_DelayComboBoxActionPerformed

    private void ChangeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ChangeButtonActionPerformed
        try {
            Task task = allModel.getTasks().get(AllTable.getSelectedRow());
            if (manager.checkVersion(task.getId(), task.getVersion()))
                new ChangeFrame(manager, task, allModel, activeModel).setVisible(true);
            else
                showWarningMessage("Something goes wrong...", "Please, click refresh button to update list of tasks");
        } catch (Exception e) {
            showWarningMessage("Something goes wrong...", "Maybe you need select a row?");
        }
    }//GEN-LAST:event_ChangeButtonActionPerformed

    //Refresh
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        manager.refresh();
        allModel.setTasks(manager.getTasks());
        activeModel.setTasks(manager.getExpiredTasks());
        activeModel.repaint();
        allModel.repaint();
    }//GEN-LAST:event_jButton1ActionPerformed

    private static void showWarningMessage(String title, String msg) {
        JOptionPane.showMessageDialog(null, msg, title, JOptionPane.WARNING_MESSAGE);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel ActiveLabel;
    private javax.swing.JPanel ActiveTab;
    private javax.swing.JTable ActiveTable;
    private javax.swing.JLabel AllLabel;
    private javax.swing.JPanel AllTab;
    private javax.swing.JTable AllTable;
    private javax.swing.JButton ChangeButton;
    private javax.swing.JButton CreateButton;
    private javax.swing.JButton DelayButton;
    private javax.swing.JComboBox DelayComboBox;
    private javax.swing.JButton DeleteButton;
    private javax.swing.JButton EndButton;
    private javax.swing.JTabbedPane TabbedPane;
    private javax.swing.JButton jButton1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    // End of variables declaration//GEN-END:variables
}

class TaskTableModel extends AbstractTableModel {

    private List<Task> tasks;

    TaskTableModel(List<Task> tasks) {
        this.tasks = tasks;
    }

    public void setTasks(List<Task> tasks) {
        this.tasks = tasks;
    }

    @Override
    public int getRowCount() {
        return tasks.size();
    }

    @Override
    public int getColumnCount() {
        return 3;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        DateFormat f = new SimpleDateFormat("dd/MM/yyyy-HH:mm");
        switch (columnIndex) {
            case 0:
                return tasks.get(rowIndex).getName();
            case 1:
                return f.format(tasks.get(rowIndex).getDate());
            case 2:
                return tasks.get(rowIndex).getDescription();
        }
        return null;
    }

    @Override
    public String getColumnName(int column) {
        switch (column) {
            case 0:
                return "Name";
            case 1:
                return "Date";
            case 2:
                return "Description";
        }
        return "";
    }

    public List<Task> getTasks() {
        return tasks;
    }

    public void repaint() {
        fireTableDataChanged();
    }
}

